﻿using Datav.Design.Datas.Pocos;
using XCode;
using Zdap.Common;
using Zdap.Common.AutoMapper;
using Zdap.Common.Extensions;
using Zdap.Common.IdGenerate;
using Zdap.XCode;
using Zdap.XCode.Service;

namespace Datav.Design.IService
{
    /// <summary>
    ///
    /// </summary>
    public class ProjectComsService : BaseService<ProjectComs, ComsModelDto>, IProjectComsService
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="currentUser"></param>
        /// <returns></returns>
        public override async ValueTask<ResponseContext<long>> Save(ComsModelDto dto, UserTicket currentUser)
        {
          
            var comsList = new List<ProjectComs>();
            if (dto.Children.IsNotNullAndEmpty())
            {
                int index = 0; // 初始化序号
                dto.Recursive(item => item.Children.Select(s => s.MapTo<ComsModelDto>()),
                    (current, parent) =>
                    {
                        var com = current.MapTo<ProjectComs>();
                        com.ParentId = parent.Id;
                        var paths = com.Id + ",";
                        if (paths != null) { 

                        }
                        if (parent.ParentId == 0)
                        {
                            parent.Paths = parent.Id + ",";
                        }

                        var path = (parent == null ? current.Id : $"{(parent).Paths?.TrimEnd(',')},{current.Id}") + ",";
                        current.Paths = path;
                        com.Paths = path;
                   
                        com.Sort = ++index;
                        comsList.Add(com);
                    }
                );
            }

            var data = await base.Save(dto, currentUser);//

            comsList.Add(new ProjectComs { Id = data.Data, Paths = dto.Paths, ParentId = dto.ParentId });
            comsList.Upsert(CommonService.GetEntityDataColumn<ProjectComs>(), [ProjectComs._.ParentId, ProjectComs._.Paths], null);

            return await Task.FromResult(data);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <param name="currentUser"></param>
        /// <returns></returns>
        public override async ValueTask<ResponseContext<List<long>>> BatchSave(SavaListModel<ComsModelDto> model, UserTicket currentUser)
        {
            model.Dtos.ForEach(s =>
            {
                s.Paths = s.ParentId + "," + s.Id + ",";
            });
            var data = await base.BatchSave(model, currentUser);
            return await Task.FromResult(data);
        }


        /// <summary>
        ///
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        protected override async ValueTask<ResponseContext<bool>> AddValidate(ComsModelDto dto)
        {
            var result = new ResponseContext<bool>();
            if (dto.ProjectId == 0)
            {
                return await Task.FromResult(result.SetError("所属项目Id不能为0！"));
            }
            result = await Verify(dto, result);
            if (!result.IsSuccess)
            {
                return result;
            }
            return await base.AddValidate(dto);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        protected override async ValueTask<ResponseContext<bool>> UpdateValidate(ComsModelDto dto)
        {
            var result = new ResponseContext<bool>();
            if (dto.ProjectId == 0)
            {
                return await Task.FromResult(result.SetError("编辑内容项目Id不能为0！"));
            }
            result = await Verify(dto, result);

            if (!result.IsSuccess)
            {
                return result;
            }
            return await base.UpdateValidate(dto);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private async ValueTask<ResponseContext<bool>> Verify(ComsModelDto dto, ResponseContext<bool> result)
        {
            var project = await Project.FindCountAsync(Project._.Id == dto.ProjectId & Project._.IsDelete == 0);

            if (project == 0)
            {
                return await Task.FromResult(result.SetError("项目不存在！"));
            }
            return result;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public override async Task<ListResponseContext<ComsModelDto>> SearchAll(RequestParameter p)
        {
            var result = new ListResponseContext<ComsModelDto>();
            var data = await base.SearchAll(p);
            var list = data.Data.ToTree(d => d.Id, d => d.ParentId, (parent, children) => parent.Children = children);

            // var r = TreeBase.CreateTree(data.Data.ToList()).OrderBy(s => s.Sort);
            // return await Task.FromResult(result.SetSuccess(r));
            // 先找出所有根节点（ParentId == 0 的项）
            //var rootItems = list.Where(id => id.ParentId == 0).ToList();
            //// 对每个根节点递归构建子树
            //foreach (var root in rootItems)
            //{
            //    root.Children = await BulidTreeByRecursive(treeNodes: list, parentId: root.Id);
            //}
            return result.SetSuccess(list);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="currentUser"></param>
        /// <returns></returns>
        public async ValueTask<ResponseContext<ComsModelDto>> Copy(long Id, UserTicket currentUser)
        {
            var result = new ResponseContext<ComsModelDto>();
            var data = base.FindByID(Id);
            var dto = data.MapTo<ComsModelDto>();
            dto.Id = IdWorker.NextId();
            dto.Name = dto.Name + "_copy";
            if (data != null)
            {
                var paths = data.Paths;
                var Params = new Dictionary<string, object>
                {
                    [ProjectComs._.Paths] = paths
                };
                var list = await this.SearchAll(new RequestParameter() { Params = Params });
                if (list.Data.IsNotNullAndEmpty())
                {
                    dto.Children = list.Data.ForEach(s => s.Name = s.Name + "_copy");
                }
            }
            var entity = await this.Save(dto, currentUser);
            result.SetSuccess(dto);
            return await Task.FromResult(result);
        }

        /// <summary>
        /// 使用递归方法建树
        /// </summary>
        public async ValueTask<IEnumerable<ComsModelDto>> BulidTreeByRecursive(IEnumerable<ComsModelDto> treeNodes, long parentId)
        {
            var resps = new List<ComsModelDto>();
            var tempList = treeNodes.Where(c => c.ParentId == parentId).OrderBy(s => s.Sort).ToList();

            foreach (var item in tempList)
            {
                ComsModelDto node = item.MapTo<ComsModelDto>();
                node.Children = await BulidTreeByRecursive(treeNodes, node.Id);
                resps.Add(node);
            }
            return await Task.FromResult(!resps.Any() && parentId != 0 ? [] : resps);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public override async ValueTask<ResponseContext<bool>> Delete(long id, UserTicket user)
        {
            var result = await base.Delete(id, user);
            if (!result.IsSuccess)
                return result;

            //删除任务所属者
            await BatchDeleteChilds(id, user);

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public override async ValueTask<ResponseContext<bool>> DeleteIds(IEnumerable<long> ids, UserTicket user)
        {
            //var result = await base.DeleteIds(ids, user);

            if (ids.Count() > 0)
            {
                ids.ForEach(async item =>
                {
                    //删除任务所属者
                    await BatchDeleteChilds(item, user);
                });
            }

            return await Task.FromResult(new ResponseContext<bool>  ());

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        private async Task BatchDeleteChilds( long id, UserTicket user)
        {
            var coms = await ProjectComs.FindAllAsync(ProjectComs._.Paths.Contains(id + ","), null, $"{ProjectComs._.Id},{ProjectComs._.IsDelete}", 0, 0);
            //删除任务下所有的题
            coms.ForEach(s =>
            {
                s.IsDelete = 1;
                CommonService.SetUpdateProperty(s, user);
            });
            coms.Upsert(CommonService.GetEntityDataColumn<ProjectComs>(), [ProjectComs._.IsDelete, ProjectComs._.CreateBy, ProjectComs._.CreateTime]);
        }
    }
}